﻿
Imports System.Threading
Imports osi.root.formation
Imports osi.root.utils
Imports osi.root.delegates
Imports osi.root.threadpool
Imports osi.root.lock
Imports osi.root.envs
Imports osi.root.connector

Partial Public Class callback_manager
    Private Shared ReadOnly CALLBACKMANAGER_CHECK_QUEUE_LENGTH As Int64
    Private Shared ReadOnly CALLBACKMANAGER_CHECK_QUEUE_TICKS As Int64
    Private Shared ReadOnly CALLBACKMANAGER_CHECK_QUEUE_INTERVAL_TICKS As Int64
    Private Shared ReadOnly CALLBACKMANAGER_CHECK_QUEUE_UNCHANGED_CYCLE As Int64
    Private ReadOnly q As qless(Of callback_action) = Nothing
    Private ReadOnly are As AutoResetEvent = Nothing
    Private ReadOnly check_thread As Thread = Nothing

    Friend Sub trigger_check()
        are.Set()
    End Sub

    Private Sub check(ByVal c As callback_action)
        assert(Not c Is Nothing)
        assert(c.pending())
        c.action_check()
        If c.pending() Then
            q.push(c)
        Else
            assert(c.ending())
            assert_begin(c)
        End If
    End Sub

    Private Sub check_queue()
        Dim unchangedCycle As Int64 = 0
        While True
            counter.record_time_begin()
            Dim size As Int64 = 0
            size = q.size()
            Dim changed As Int64 = 0
            counter.increase(CALLBACKMANAGER_CHECK_QUEUE_LENGTH, size)
            While size > 0
                Dim c As callback_action = Nothing
                assert(q.pop(c))
                check(c)
                If Not c.pending() Then
                    changed += 1
                End If
                size -= 1
            End While
            counter.record_time_ticks(CALLBACKMANAGER_CHECK_QUEUE_TICKS)
            If changed > 0 Then
                counter.increase(CALLBACKMANAGER_CHECK_QUEUE_UNCHANGED_CYCLE, unchangedCycle)
                unchangedCycle = 0
            Else
                unchangedCycle += 1
            End If
            If application_lifetime.stopping() Then
                Exit While
            End If
            counter.record_time_begin()
            yield_wait(are)
            counter.record_time_ticks(CALLBACKMANAGER_CHECK_QUEUE_INTERVAL_TICKS)
        End While
    End Sub

    Private Sub begin_check(ByVal action As callback_action)
        check(action)
    End Sub

    Public Function check_queue_length() As Int64
        Return q.size()
    End Function
End Class
